package agents;

import extra.Position;
import game.constants.ReferenceAgent;
import game.constants.ReferenceSpecialFeature;
import graph.dijkstra.PathGraph;
import interfaces.AgentInterface;
import interfaces.impl.Agent;
import objects.SpetialFeature;
import objects.WorldObject;
import universe.Universe;
import actions.ActionModifySpetialFeature;
import actions.ActionMove;
import constants.Constants;

public class AgentMove extends Agent implements AgentInterface{
	
	//attributes needed from object
		private SpetialFeature visionRange;
		private SpetialFeature speed ;
		private SpetialFeature xObject;
		private SpetialFeature yObject;
		private SpetialFeature isMoving;
		
		//Own Attributes  
		private PathGraph graph;
		private int xTogo;
		private int yTogo;
		private double xDistance;
		private double yDistance;
		private double angle;
		private double xFinalToMove=100;
		private double yFinalToMove=100;
		private boolean move=false;
		
		private ActionMove actionMove;
		private ActionModifySpetialFeature actionModify;
		
	
		
		
		
	

	@Override
	public void updateChild(WorldObject object, Universe universe, double time) {
		

		int xActual = (int) object.getPosition().getX();
		int yActual = (int) object.getPosition().getY();
				
		if((xFinalToMove!=xObject.getValue() || yFinalToMove!=yObject.getValue())){
			//System.out.println("busco el camino a donde voy");
			graph=new PathGraph();
			xFinalToMove=xObject.getValue();
			yFinalToMove=yObject.getValue();
			//System.out.println("Stoy en x "+object.getPosition().getX()+" y"+object.getPosition().getY());
			//System.out.println("!)XTOMOVE: "+xFinalToMove+" YTOMOVE "+yFinalToMove);
		
			//System.out.println("TIEMPO EN EL AGENT MOVE1: "+time);
			graph.generateGraph(object.getPosition(),new Position(xFinalToMove,yFinalToMove),visionRange.getValue(),universe.getWorldI());
			//System.out.println("TIEMPO EN EL AGENT MOVE2: "+(System.currentTimeMillis()-time));
			
			
			//System.out.println("XTOMOVE: "+xFinalToMove+" YTOMOVE "+yFinalToMove);
			move=true;
			xTogo= (int)object.getPosition().getX();
			yTogo= (int)object.getPosition().getY();
		}
		
			
			if((xTogo!=xActual || yTogo!=yActual) && move){
				
				//if i can get here that means that i'm mooving
				
				
				double distance;
				distance = (speed.getValue()*time);
				xDistance=xDistance+ Math.cos(angle)*distance;
				yDistance=yDistance+ Math.sin(angle)*distance;
				
				//para las x
				if(xTogo>xActual){
					while(xDistance>=1 ){
						xActual++;
						xDistance-=1;
						
						if(xActual>xTogo){
							xActual=xTogo;
							
						
							break;
						}
					}
				}else{
					if(xTogo<xActual){
						while(xDistance>=1 ){
							xActual--;
							xDistance-=1;
						
							if(xActual<xTogo ){
								xActual=xTogo;
						
								break;
							}
						}
					}
				}
				//para las y
				if(yTogo>yActual){
					while(yDistance>=1 ){
						yActual++;
						yDistance-=1;
						
						if(yActual>yTogo ){
							yActual=yTogo;
						
							break;
						}
					}
				}else{
					if(yTogo<yActual){
						while(yDistance>=1){
							yActual--;
							yDistance-=1;
						
							if(yActual<yTogo ){
								yActual=yTogo;
						
								break;
							}
						}
					}
				}
				
				generateActionMove(object,xActual,yActual,universe);
				
			}
			else{
				
				
				Position position = graph.getPositionToMove();
				if(position!=null){
					xTogo=(int) position.getX();
					yTogo=(int) position.getY();
					setDesiredPosition(xTogo, yTogo,object);
				}else{
					
					generateActionModifyMoving(object,universe);
					
				}
				//ya llegue
				
				
			}
		
			//System.out.println("TIEMPO EN EL AGENT MOVE2"+(System.currentTimeMillis()-time));
		//object.setPosition(new Position(xActual,yActual));
	}

	private void generateActionModifyMoving(WorldObject object,Universe universe) {
		
		actionModify.setSource(object);
		actionModify.setTarget(object);
		actionModify.setFeatureId(ReferenceSpecialFeature.SPETIAL_FEATURE_IS_MOVING);
		actionModify.setValue(Constants.FALSE);
		universe.setAction(actionModify);
		//actionModify.setActive(true);
		//object.setImmediatlyActionToDo(actionModify);
		
	}

	private void generateActionMove(WorldObject object,double xActual,double yActual,Universe universe) {
		
		actionMove.setSource(object);
		actionMove.setTarget(object);
		actionMove.setPriority(priority);
		actionMove.setWaitTimeToExecute(0);
		actionMove.setExecuteTime(0);
		actionMove.setX(xActual);
		actionMove.setY(yActual);
		universe.setAction(actionMove);
		
		
		actionModify.setSource(object);
		actionModify.setTarget(object);
		actionModify.setFeatureId(ReferenceSpecialFeature.SPETIAL_FEATURE_IS_MOVING);
		actionModify.setValue(Constants.TRUE);
		universe.setAction(actionModify);
		//actionMove.setActive(true);
		//object.setImmediatlyActionToDo(actionMove);
		
	}

	
	@Override
	public String getName() {
		return "Moverse";
	}
	
	private void setDesiredPosition(int x, int y,WorldObject obj) {
		xTogo=x;
		yTogo=y;
		calculeAngle(obj);
		xDistance=0;
		yDistance=0;	
		
	}
	
	private void calculeAngle(WorldObject obj){
		int y = yTogo-(int)obj.getPosition().getY();
		int x = xTogo-(int)obj.getPosition().getX();
		if(x<0)
			x=x*-1;
		if(y<0)
			y=y*-1;
		angle = Math.atan2(y,x);
	}
	
	
	public AgentMove(){
		super();
		graph=new  PathGraph();
		xTogo=0;
		yTogo=0;
		
	}
	
	
	@Override
	public void setName(String name) {
		this.name=name;
		
	}

	@Override
	public void initializeActionList() {
		actionMove= new ActionMove();
		listActions.add(actionMove);
		
		actionModify= new ActionModifySpetialFeature();
		listActions.add(actionModify);
		
	}

	@Override
	public void initializeSpecialFeatures() {

		speed = new SpetialFeature(ReferenceSpecialFeature.SPETIAL_FEATURE_SPEED);
		listFeatures.add(speed);
		
		xObject =  new SpetialFeature(ReferenceSpecialFeature.SPETIAL_FEATURE_X_TO_MOVE);
		listFeatures.add(xObject);
		
		yObject =  new SpetialFeature(ReferenceSpecialFeature.SPETIAL_FEATURE_Y_TO_MOVE);
		listFeatures.add(yObject);
		
		isMoving =  new SpetialFeature(ReferenceSpecialFeature.SPETIAL_FEATURE_IS_MOVING);
		listFeatures.add(isMoving);
		
		visionRange =  new SpetialFeature(ReferenceSpecialFeature.SPETIAL_FEATURE_VISION_RANGE);
		listFeatures.add(visionRange);
		
	}

	@Override
	public void initializeName() {
		name="Moverse";
		
	}

	@Override
	public void initializeId() {
		this.id=ReferenceAgent.AGENT_MOVE;
		
	}
	
}
